package com.itheima.service.mongo.impl;

import cn.hutool.core.collection.CollectionUtil;
import com.itheima.domain.mongo.*;
import com.itheima.service.mongo.MovementService;
import com.itheima.util.ConstantUtil;
import com.itheima.vo.PageBeanVo;
import com.sun.org.apache.xpath.internal.operations.Or;
import org.apache.dubbo.config.annotation.Service;
import org.bson.types.ObjectId;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Sort;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.data.mongodb.core.query.Criteria;
import org.springframework.data.mongodb.core.query.Query;

import java.util.ArrayList;
import java.util.List;

@Service
public class MovementServiceImpl implements MovementService {

    @Autowired
    private MongoTemplate mongoTemplate;

    @Autowired
    private IdService idService;

    @Override
    public void saveMovement(Movement movement) {
        //0.设置pid
        Long pid = idService.getNextId(ConstantUtil.MOVEMENT_ID);
        movement.setPid(pid);

        //1. 向动态详情表中插入动态数据,获取动态id
        mongoTemplate.save(movement);
        ObjectId movementId = movement.getId();//主键返回

        //2. 向自己的动态表中插入动态id
        //2-1 组装一个我的动态对象
        MyMovement myMovement = new MyMovement();
        myMovement.setPublishId(movementId);
        myMovement.setCreated(System.currentTimeMillis());
        //2-2 保存我的动态
        mongoTemplate.save(myMovement, ConstantUtil.MOVEMENT_MINE + movement.getUserId());

        //3. 通过朋友关系表查询出自己所有的朋友
        //3-1 组装查询条件
        Query query = new Query(
                Criteria.where("userId").is(movement.getUserId())
        );
        //3-2 查询到我的所有好友
        List<Friend> friendList = mongoTemplate.find(query, Friend.class);

        //4. 向每个朋友的好友表插入动态id和发布人id
        if (CollectionUtil.isNotEmpty(friendList)) {
            for (Friend friend : friendList) {
                //4-1 获取到其中一个好友的id
                Long friendId = friend.getFriendId();

                //4-2 组装一个好友动态
                FriendMovement friendMovement = new FriendMovement();
                friendMovement.setPublishId(movementId);
                friendMovement.setUserId(movement.getUserId());
                friendMovement.setCreated(System.currentTimeMillis());

                //4-3 保存到好友表
                mongoTemplate.save(friendMovement, ConstantUtil.MOVEMENT_FRIEND + friendId);
            }
        }
    }

    @Override
    public PageBeanVo findMovementByUserId(Long userId, Integer pageNum, Integer pageSize) {
        //1. 从我的动态表中查询动态id集合
        Query query = new Query()
                .with(Sort.by(Sort.Order.desc("created")))
                .skip((pageNum - 1) * pageSize).limit(pageSize);//limit  startIndex,pageSize

        List<MyMovement> myMovementList = mongoTemplate.find(query, MyMovement.class, ConstantUtil.MOVEMENT_MINE + userId);
        //2. 遍历动态id集合,获取到动态id
        ArrayList<Movement> movementList = new ArrayList<>();
        if (CollectionUtil.isNotEmpty(myMovementList)) {
            for (MyMovement myMovement : myMovementList) {
                ObjectId movementId = myMovement.getPublishId();

                //3. 根据动态id查询动态详情
                Movement movement = mongoTemplate.findById(movementId, Movement.class);

                //只有状态审核通过的,才能返回
                if (movement.getState() == 1) {
                    movementList.add(movement);
                }
            }
        }

        //4. 统计总记录数
        long count = mongoTemplate.count(query, MyMovement.class, ConstantUtil.MOVEMENT_MINE + userId);

        //5. 封装返回vo
        return new PageBeanVo(pageNum, pageSize, count, movementList);
    }

    @Override
    public PageBeanVo findFriendMovementByUserId(Long userId, Integer pageNum, Integer pageSize) {
        //1. 查询我的好友动态表,获取到动态id
        Query query = new Query()
                .with(Sort.by(Sort.Order.desc("created")))
                .skip((pageNum - 1) * pageSize).limit(pageSize);
        List<FriendMovement> friendMovementList = mongoTemplate.find(query, FriendMovement.class, ConstantUtil.MOVEMENT_FRIEND + userId);

        //2. 遍历动态id集合,获取到动态id
        ArrayList<Movement> movementList = new ArrayList<>();
        if (CollectionUtil.isNotEmpty(friendMovementList)) {
            for (FriendMovement friendMovement : friendMovementList) {
                ObjectId movementId = friendMovement.getPublishId();

                //3. 根据动态id查询动态详情
                Movement movement = mongoTemplate.findById(movementId, Movement.class);
                //只有状态审核通过的,才能返回
                if (movement.getState() == 1) {
                    movementList.add(movement);
                }
            }
        }

        //4. 统计总记录数
        long count = mongoTemplate.count(query, FriendMovement.class, ConstantUtil.MOVEMENT_FRIEND + userId);

        //5. 封装返回vo
        return new PageBeanVo(pageNum, pageSize, count, movementList);
    }

    @Override
    public PageBeanVo findRecommendMovement(Long userId, Integer pageNum, Integer pageSize) {
        //1. 根据userId查询推荐表,分页找到推荐给userid的动态集合
        Query query = new Query(
                Criteria.where("userId").is(userId)
        ).with(Sort.by(Sort.Order.desc("score"), Sort.Order.desc("created")))
                .skip((pageNum - 1) * pageSize).limit(pageSize);
        List<RecommendMovement> recommendMovementList = mongoTemplate.find(query, RecommendMovement.class);

        //2. 遍历上面查到的集合,获取动态id
        ArrayList<Movement> movementList = new ArrayList<>();
        if (CollectionUtil.isNotEmpty(recommendMovementList)) {
            for (RecommendMovement recommendMovement : recommendMovementList) {
                ObjectId movementId = recommendMovement.getPublishId();

                //3. 根据动态id查询动态详情
                Movement movement = mongoTemplate.findById(movementId, Movement.class);
                //只有状态审核通过的,才能返回
                if (movement.getState() == 1) {
                    movementList.add(movement);
                }
            }
        }

        //4. 统计数量
        long count = mongoTemplate.count(query, RecommendMovement.class);

        //5. 封装返回vo
        return new PageBeanVo(pageNum, pageSize, count, movementList);
    }

    @Override
    public Movement findMovementById(String movementId) {
        return mongoTemplate.findById(movementId, Movement.class);
    }

    @Override
    public PageBeanVo findUserMovementList(Long uid, Integer stateInt, Integer pageNum, Integer pageSize) {
        //1. 构建查询条件
        Query query = new Query().with(Sort.by(Sort.Order.desc("created"))).skip((pageNum - 1) * pageSize).limit(pageSize);
        if (uid != null) {
            query.addCriteria(Criteria.where("userId").is(uid));
        }
        if (stateInt != null) {
            query.addCriteria(Criteria.where("state").is(stateInt));
        }

        //2. 查询
        List<Movement> movementList = mongoTemplate.find(query, Movement.class);

        //3. 统计
        long count = mongoTemplate.count(query, Movement.class);

        //4. 返回
        return new PageBeanVo(pageNum, pageSize, count, movementList);
    }

    @Override
    public void updateMovement(Movement movement) {
        mongoTemplate.save(movement);
    }
    @Override
    public void updateMovementState(Movement movement) {
        mongoTemplate.save(movement);
    }
}
